/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package daos;

import daos.exceptions.IllegalOrphanException;
import daos.exceptions.NonexistentEntityException;
import daos.exceptions.PreexistingEntityException;
import daos.exceptions.RollbackFailureException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Competencia;
import java.util.ArrayList;
import java.util.Collection;
import entidades.Evento;
import entidades.Usuario;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author usuario
 */
public class UsuarioJpaController implements Serializable {

    public UsuarioJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) throws PreexistingEntityException, RollbackFailureException, Exception {
        if (usuario.getCompetenciaCollection() == null) {
            usuario.setCompetenciaCollection(new ArrayList<Competencia>());
        }
        if (usuario.getCompetenciaCollection1() == null) {
            usuario.setCompetenciaCollection1(new ArrayList<Competencia>());
        }
        if (usuario.getEventoCollection() == null) {
            usuario.setEventoCollection(new ArrayList<Evento>());
        }
        if (usuario.getEventoCollection1() == null) {
            usuario.setEventoCollection1(new ArrayList<Evento>());
        }
        if (usuario.getEventoCollection2() == null) {
            usuario.setEventoCollection2(new ArrayList<Evento>());
        }
        if (usuario.getEventoCollection3() == null) {
            usuario.setEventoCollection3(new ArrayList<Evento>());
        }
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Collection<Competencia> attachedCompetenciaCollection = new ArrayList<Competencia>();
            for (Competencia competenciaCollectionCompetenciaToAttach : usuario.getCompetenciaCollection()) {
                competenciaCollectionCompetenciaToAttach = em.getReference(competenciaCollectionCompetenciaToAttach.getClass(), competenciaCollectionCompetenciaToAttach.getIdCompetencia());
                attachedCompetenciaCollection.add(competenciaCollectionCompetenciaToAttach);
            }
            usuario.setCompetenciaCollection(attachedCompetenciaCollection);
            Collection<Competencia> attachedCompetenciaCollection1 = new ArrayList<Competencia>();
            for (Competencia competenciaCollection1CompetenciaToAttach : usuario.getCompetenciaCollection1()) {
                competenciaCollection1CompetenciaToAttach = em.getReference(competenciaCollection1CompetenciaToAttach.getClass(), competenciaCollection1CompetenciaToAttach.getIdCompetencia());
                attachedCompetenciaCollection1.add(competenciaCollection1CompetenciaToAttach);
            }
            usuario.setCompetenciaCollection1(attachedCompetenciaCollection1);
            Collection<Evento> attachedEventoCollection = new ArrayList<Evento>();
            for (Evento eventoCollectionEventoToAttach : usuario.getEventoCollection()) {
                eventoCollectionEventoToAttach = em.getReference(eventoCollectionEventoToAttach.getClass(), eventoCollectionEventoToAttach.getIdEvento());
                attachedEventoCollection.add(eventoCollectionEventoToAttach);
            }
            usuario.setEventoCollection(attachedEventoCollection);
            Collection<Evento> attachedEventoCollection1 = new ArrayList<Evento>();
            for (Evento eventoCollection1EventoToAttach : usuario.getEventoCollection1()) {
                eventoCollection1EventoToAttach = em.getReference(eventoCollection1EventoToAttach.getClass(), eventoCollection1EventoToAttach.getIdEvento());
                attachedEventoCollection1.add(eventoCollection1EventoToAttach);
            }
            usuario.setEventoCollection1(attachedEventoCollection1);
            Collection<Evento> attachedEventoCollection2 = new ArrayList<Evento>();
            for (Evento eventoCollection2EventoToAttach : usuario.getEventoCollection2()) {
                eventoCollection2EventoToAttach = em.getReference(eventoCollection2EventoToAttach.getClass(), eventoCollection2EventoToAttach.getIdEvento());
                attachedEventoCollection2.add(eventoCollection2EventoToAttach);
            }
            usuario.setEventoCollection2(attachedEventoCollection2);
            Collection<Evento> attachedEventoCollection3 = new ArrayList<Evento>();
            for (Evento eventoCollection3EventoToAttach : usuario.getEventoCollection3()) {
                eventoCollection3EventoToAttach = em.getReference(eventoCollection3EventoToAttach.getClass(), eventoCollection3EventoToAttach.getIdEvento());
                attachedEventoCollection3.add(eventoCollection3EventoToAttach);
            }
            usuario.setEventoCollection3(attachedEventoCollection3);
            em.persist(usuario);
            for (Competencia competenciaCollectionCompetencia : usuario.getCompetenciaCollection()) {
                competenciaCollectionCompetencia.getUsuarioCollection().add(usuario);
                competenciaCollectionCompetencia = em.merge(competenciaCollectionCompetencia);
            }
            for (Competencia competenciaCollection1Competencia : usuario.getCompetenciaCollection1()) {
                competenciaCollection1Competencia.getUsuarioCollection().add(usuario);
                competenciaCollection1Competencia = em.merge(competenciaCollection1Competencia);
            }
            for (Evento eventoCollectionEvento : usuario.getEventoCollection()) {
                Usuario oldUsuarioOfEventoCollectionEvento = eventoCollectionEvento.getUsuario();
                eventoCollectionEvento.setUsuario(usuario);
                eventoCollectionEvento = em.merge(eventoCollectionEvento);
                if (oldUsuarioOfEventoCollectionEvento != null) {
                    oldUsuarioOfEventoCollectionEvento.getEventoCollection().remove(eventoCollectionEvento);
                    oldUsuarioOfEventoCollectionEvento = em.merge(oldUsuarioOfEventoCollectionEvento);
                }
            }
            for (Evento eventoCollection1Evento : usuario.getEventoCollection1()) {
                Usuario oldUsuario1OfEventoCollection1Evento = eventoCollection1Evento.getUsuario1();
                eventoCollection1Evento.setUsuario1(usuario);
                eventoCollection1Evento = em.merge(eventoCollection1Evento);
                if (oldUsuario1OfEventoCollection1Evento != null) {
                    oldUsuario1OfEventoCollection1Evento.getEventoCollection1().remove(eventoCollection1Evento);
                    oldUsuario1OfEventoCollection1Evento = em.merge(oldUsuario1OfEventoCollection1Evento);
                }
            }
            for (Evento eventoCollection2Evento : usuario.getEventoCollection2()) {
                Usuario oldUsuario2OfEventoCollection2Evento = eventoCollection2Evento.getUsuario2();
                eventoCollection2Evento.setUsuario2(usuario);
                eventoCollection2Evento = em.merge(eventoCollection2Evento);
                if (oldUsuario2OfEventoCollection2Evento != null) {
                    oldUsuario2OfEventoCollection2Evento.getEventoCollection2().remove(eventoCollection2Evento);
                    oldUsuario2OfEventoCollection2Evento = em.merge(oldUsuario2OfEventoCollection2Evento);
                }
            }
            for (Evento eventoCollection3Evento : usuario.getEventoCollection3()) {
                Usuario oldUsuario3OfEventoCollection3Evento = eventoCollection3Evento.getUsuario3();
                eventoCollection3Evento.setUsuario3(usuario);
                eventoCollection3Evento = em.merge(eventoCollection3Evento);
                if (oldUsuario3OfEventoCollection3Evento != null) {
                    oldUsuario3OfEventoCollection3Evento.getEventoCollection3().remove(eventoCollection3Evento);
                    oldUsuario3OfEventoCollection3Evento = em.merge(oldUsuario3OfEventoCollection3Evento);
                }
            }
            //utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            if (findUsuario(usuario.getCedula()) != null) {
                throw new PreexistingEntityException("Usuario " + usuario + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getCedula());
            Collection<Competencia> competenciaCollectionOld = persistentUsuario.getCompetenciaCollection();
            Collection<Competencia> competenciaCollectionNew = usuario.getCompetenciaCollection();
            Collection<Competencia> competenciaCollection1Old = persistentUsuario.getCompetenciaCollection1();
            Collection<Competencia> competenciaCollection1New = usuario.getCompetenciaCollection1();
            Collection<Evento> eventoCollectionOld = persistentUsuario.getEventoCollection();
            Collection<Evento> eventoCollectionNew = usuario.getEventoCollection();
            Collection<Evento> eventoCollection1Old = persistentUsuario.getEventoCollection1();
            Collection<Evento> eventoCollection1New = usuario.getEventoCollection1();
            Collection<Evento> eventoCollection2Old = persistentUsuario.getEventoCollection2();
            Collection<Evento> eventoCollection2New = usuario.getEventoCollection2();
            Collection<Evento> eventoCollection3Old = persistentUsuario.getEventoCollection3();
            Collection<Evento> eventoCollection3New = usuario.getEventoCollection3();
            List<String> illegalOrphanMessages = null;
            for (Evento eventoCollection3OldEvento : eventoCollection3Old) {
                if (!eventoCollection3New.contains(eventoCollection3OldEvento)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Evento " + eventoCollection3OldEvento + " since its usuario3 field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Competencia> attachedCompetenciaCollectionNew = new ArrayList<Competencia>();
            for (Competencia competenciaCollectionNewCompetenciaToAttach : competenciaCollectionNew) {
                competenciaCollectionNewCompetenciaToAttach = em.getReference(competenciaCollectionNewCompetenciaToAttach.getClass(), competenciaCollectionNewCompetenciaToAttach.getIdCompetencia());
                attachedCompetenciaCollectionNew.add(competenciaCollectionNewCompetenciaToAttach);
            }
            competenciaCollectionNew = attachedCompetenciaCollectionNew;
            usuario.setCompetenciaCollection(competenciaCollectionNew);
            Collection<Competencia> attachedCompetenciaCollection1New = new ArrayList<Competencia>();
            for (Competencia competenciaCollection1NewCompetenciaToAttach : competenciaCollection1New) {
                competenciaCollection1NewCompetenciaToAttach = em.getReference(competenciaCollection1NewCompetenciaToAttach.getClass(), competenciaCollection1NewCompetenciaToAttach.getIdCompetencia());
                attachedCompetenciaCollection1New.add(competenciaCollection1NewCompetenciaToAttach);
            }
            competenciaCollection1New = attachedCompetenciaCollection1New;
            usuario.setCompetenciaCollection1(competenciaCollection1New);
            Collection<Evento> attachedEventoCollectionNew = new ArrayList<Evento>();
            for (Evento eventoCollectionNewEventoToAttach : eventoCollectionNew) {
                eventoCollectionNewEventoToAttach = em.getReference(eventoCollectionNewEventoToAttach.getClass(), eventoCollectionNewEventoToAttach.getIdEvento());
                attachedEventoCollectionNew.add(eventoCollectionNewEventoToAttach);
            }
            eventoCollectionNew = attachedEventoCollectionNew;
            usuario.setEventoCollection(eventoCollectionNew);
            Collection<Evento> attachedEventoCollection1New = new ArrayList<Evento>();
            for (Evento eventoCollection1NewEventoToAttach : eventoCollection1New) {
                eventoCollection1NewEventoToAttach = em.getReference(eventoCollection1NewEventoToAttach.getClass(), eventoCollection1NewEventoToAttach.getIdEvento());
                attachedEventoCollection1New.add(eventoCollection1NewEventoToAttach);
            }
            eventoCollection1New = attachedEventoCollection1New;
            usuario.setEventoCollection1(eventoCollection1New);
            Collection<Evento> attachedEventoCollection2New = new ArrayList<Evento>();
            for (Evento eventoCollection2NewEventoToAttach : eventoCollection2New) {
                eventoCollection2NewEventoToAttach = em.getReference(eventoCollection2NewEventoToAttach.getClass(), eventoCollection2NewEventoToAttach.getIdEvento());
                attachedEventoCollection2New.add(eventoCollection2NewEventoToAttach);
            }
            eventoCollection2New = attachedEventoCollection2New;
            usuario.setEventoCollection2(eventoCollection2New);
            Collection<Evento> attachedEventoCollection3New = new ArrayList<Evento>();
            for (Evento eventoCollection3NewEventoToAttach : eventoCollection3New) {
                eventoCollection3NewEventoToAttach = em.getReference(eventoCollection3NewEventoToAttach.getClass(), eventoCollection3NewEventoToAttach.getIdEvento());
                attachedEventoCollection3New.add(eventoCollection3NewEventoToAttach);
            }
            eventoCollection3New = attachedEventoCollection3New;
            usuario.setEventoCollection3(eventoCollection3New);
            usuario = em.merge(usuario);
            for (Competencia competenciaCollectionOldCompetencia : competenciaCollectionOld) {
                if (!competenciaCollectionNew.contains(competenciaCollectionOldCompetencia)) {
                    competenciaCollectionOldCompetencia.getUsuarioCollection().remove(usuario);
                    competenciaCollectionOldCompetencia = em.merge(competenciaCollectionOldCompetencia);
                }
            }
            for (Competencia competenciaCollectionNewCompetencia : competenciaCollectionNew) {
                if (!competenciaCollectionOld.contains(competenciaCollectionNewCompetencia)) {
                    competenciaCollectionNewCompetencia.getUsuarioCollection().add(usuario);
                    competenciaCollectionNewCompetencia = em.merge(competenciaCollectionNewCompetencia);
                }
            }
            for (Competencia competenciaCollection1OldCompetencia : competenciaCollection1Old) {
                if (!competenciaCollection1New.contains(competenciaCollection1OldCompetencia)) {
                    competenciaCollection1OldCompetencia.getUsuarioCollection().remove(usuario);
                    competenciaCollection1OldCompetencia = em.merge(competenciaCollection1OldCompetencia);
                }
            }
            for (Competencia competenciaCollection1NewCompetencia : competenciaCollection1New) {
                if (!competenciaCollection1Old.contains(competenciaCollection1NewCompetencia)) {
                    competenciaCollection1NewCompetencia.getUsuarioCollection().add(usuario);
                    competenciaCollection1NewCompetencia = em.merge(competenciaCollection1NewCompetencia);
                }
            }
            for (Evento eventoCollectionOldEvento : eventoCollectionOld) {
                if (!eventoCollectionNew.contains(eventoCollectionOldEvento)) {
                    eventoCollectionOldEvento.setUsuario(null);
                    eventoCollectionOldEvento = em.merge(eventoCollectionOldEvento);
                }
            }
            for (Evento eventoCollectionNewEvento : eventoCollectionNew) {
                if (!eventoCollectionOld.contains(eventoCollectionNewEvento)) {
                    Usuario oldUsuarioOfEventoCollectionNewEvento = eventoCollectionNewEvento.getUsuario();
                    eventoCollectionNewEvento.setUsuario(usuario);
                    eventoCollectionNewEvento = em.merge(eventoCollectionNewEvento);
                    if (oldUsuarioOfEventoCollectionNewEvento != null && !oldUsuarioOfEventoCollectionNewEvento.equals(usuario)) {
                        oldUsuarioOfEventoCollectionNewEvento.getEventoCollection().remove(eventoCollectionNewEvento);
                        oldUsuarioOfEventoCollectionNewEvento = em.merge(oldUsuarioOfEventoCollectionNewEvento);
                    }
                }
            }
            for (Evento eventoCollection1OldEvento : eventoCollection1Old) {
                if (!eventoCollection1New.contains(eventoCollection1OldEvento)) {
                    eventoCollection1OldEvento.setUsuario1(null);
                    eventoCollection1OldEvento = em.merge(eventoCollection1OldEvento);
                }
            }
            for (Evento eventoCollection1NewEvento : eventoCollection1New) {
                if (!eventoCollection1Old.contains(eventoCollection1NewEvento)) {
                    Usuario oldUsuario1OfEventoCollection1NewEvento = eventoCollection1NewEvento.getUsuario1();
                    eventoCollection1NewEvento.setUsuario1(usuario);
                    eventoCollection1NewEvento = em.merge(eventoCollection1NewEvento);
                    if (oldUsuario1OfEventoCollection1NewEvento != null && !oldUsuario1OfEventoCollection1NewEvento.equals(usuario)) {
                        oldUsuario1OfEventoCollection1NewEvento.getEventoCollection1().remove(eventoCollection1NewEvento);
                        oldUsuario1OfEventoCollection1NewEvento = em.merge(oldUsuario1OfEventoCollection1NewEvento);
                    }
                }
            }
            for (Evento eventoCollection2OldEvento : eventoCollection2Old) {
                if (!eventoCollection2New.contains(eventoCollection2OldEvento)) {
                    eventoCollection2OldEvento.setUsuario2(null);
                    eventoCollection2OldEvento = em.merge(eventoCollection2OldEvento);
                }
            }
            for (Evento eventoCollection2NewEvento : eventoCollection2New) {
                if (!eventoCollection2Old.contains(eventoCollection2NewEvento)) {
                    Usuario oldUsuario2OfEventoCollection2NewEvento = eventoCollection2NewEvento.getUsuario2();
                    eventoCollection2NewEvento.setUsuario2(usuario);
                    eventoCollection2NewEvento = em.merge(eventoCollection2NewEvento);
                    if (oldUsuario2OfEventoCollection2NewEvento != null && !oldUsuario2OfEventoCollection2NewEvento.equals(usuario)) {
                        oldUsuario2OfEventoCollection2NewEvento.getEventoCollection2().remove(eventoCollection2NewEvento);
                        oldUsuario2OfEventoCollection2NewEvento = em.merge(oldUsuario2OfEventoCollection2NewEvento);
                    }
                }
            }
            for (Evento eventoCollection3NewEvento : eventoCollection3New) {
                if (!eventoCollection3Old.contains(eventoCollection3NewEvento)) {
                    Usuario oldUsuario3OfEventoCollection3NewEvento = eventoCollection3NewEvento.getUsuario3();
                    eventoCollection3NewEvento.setUsuario3(usuario);
                    eventoCollection3NewEvento = em.merge(eventoCollection3NewEvento);
                    if (oldUsuario3OfEventoCollection3NewEvento != null && !oldUsuario3OfEventoCollection3NewEvento.equals(usuario)) {
                        oldUsuario3OfEventoCollection3NewEvento.getEventoCollection3().remove(eventoCollection3NewEvento);
                        oldUsuario3OfEventoCollection3NewEvento = em.merge(oldUsuario3OfEventoCollection3NewEvento);
                    }
                }
            }
            //utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = usuario.getCedula();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getCedula();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Evento> eventoCollection3OrphanCheck = usuario.getEventoCollection3();
            for (Evento eventoCollection3OrphanCheckEvento : eventoCollection3OrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Evento " + eventoCollection3OrphanCheckEvento + " in its eventoCollection3 field has a non-nullable usuario3 field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Competencia> competenciaCollection = usuario.getCompetenciaCollection();
            for (Competencia competenciaCollectionCompetencia : competenciaCollection) {
                competenciaCollectionCompetencia.getUsuarioCollection().remove(usuario);
                competenciaCollectionCompetencia = em.merge(competenciaCollectionCompetencia);
            }
            Collection<Competencia> competenciaCollection1 = usuario.getCompetenciaCollection1();
            for (Competencia competenciaCollection1Competencia : competenciaCollection1) {
                competenciaCollection1Competencia.getUsuarioCollection().remove(usuario);
                competenciaCollection1Competencia = em.merge(competenciaCollection1Competencia);
            }
            Collection<Evento> eventoCollection = usuario.getEventoCollection();
            for (Evento eventoCollectionEvento : eventoCollection) {
                eventoCollectionEvento.setUsuario(null);
                eventoCollectionEvento = em.merge(eventoCollectionEvento);
            }
            Collection<Evento> eventoCollection1 = usuario.getEventoCollection1();
            for (Evento eventoCollection1Evento : eventoCollection1) {
                eventoCollection1Evento.setUsuario1(null);
                eventoCollection1Evento = em.merge(eventoCollection1Evento);
            }
            Collection<Evento> eventoCollection2 = usuario.getEventoCollection2();
            for (Evento eventoCollection2Evento : eventoCollection2) {
                eventoCollection2Evento.setUsuario2(null);
                eventoCollection2Evento = em.merge(eventoCollection2Evento);
            }
            em.remove(usuario);
            //utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
